﻿using System.Collections.Generic;
using GeneticAlgorithms.Genomes;
using GeneticAlgorithms.Populations;
using GeneticAlgorithms.Tools;

namespace GeneticAlgorithms.Operators.Selection
{
    /// <summary>
    /// Implements selection by tournament.
    /// </summary>
    /// <typeparam name="TGenome">The type of the genome.</typeparam>
    /// <typeparam name="TGene">The type of the gene.</typeparam>
    public class TounamentSelector<TGenome, TGene> : IGeneticSelector<TGenome, TGene> where TGenome : IGenome<TGene>
    {
        #region IGeneticSelector<TGene> Members

        /// <summary>
        /// Selects the genomes.
        /// </summary>
        /// <param name="population">The population from which
        /// the selected genomes will be picked.</param>
        /// <param name="selectCount">The count of genomes to select.</param>
        /// <returns>A genome of selected genomes.</returns>
        public IEnumerable<TGenome> SelectGenomes(
            IPopulation<TGenome, TGene> population,
            int selectCount)
        {
            for (int i = 0; i < selectCount; ++i)
            {
                int firstPos = GeneticRandomGenerator.Default.Next(population.Count);
                int secondPos = GeneticRandomGenerator.Default.Next(population.Count);
                if (firstPos != secondPos)
                {
                    if (population[secondPos].Fitness > population[firstPos].Fitness)
                    {
                        firstPos = secondPos;
                    }
                }

                yield return population[firstPos];
            }
        }

        #endregion
    }
}
